package com.xbongbong.workflow.service.strategy.data.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.message.domain.entity.PushSetEntity;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.log.constant.CrmLogMemoConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerDynamicAddDTO;
import com.xbongbong.pro.enums.CommunicatePlanNotifyTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.message.constant.CommunicatePlanPushConstant;
import com.xbongbong.pro.message.enums.PushObjectTypeEnum;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.help.PushHelper;
import com.xbongbong.pro.message.model.PushSetModel;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.message.pushset.CommunicatePlanPushSet;
import com.xbongbong.pro.message.service.MessageService;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CommunicatePlanUserEntity;
import com.xbongbong.saas.domain.entity.CustomerUserEntity;
import com.xbongbong.saas.enums.ExecutorCheckBoxEnum;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CommunicatePlanEnum;
import com.xbongbong.saas.model.CommunicatePlanUserModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.service.CustomerCommunicateService;
import com.xbongbong.saas.service.DingRobotService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.workflow.pojo.Data;
import com.xbongbong.workflow.pojo.User;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.service.strategy.data.AbstractWorkflowDataStrategy;
import com.xbongbong.workflow.service.strategy.data.WorkflowDataProcessStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerFromFormData;

/**
 * 
 * @author 魏荣杰
 *
 */
@Service
@Slf4j
public class WorkflowCommunicatePlanStrategy extends AbstractWorkflowDataStrategy implements WorkflowDataProcessStrategy {

    @Resource
    private PushSetModel pushSetModel;
    @Resource
    private MessageService messageService;
    @Resource
    private PushHelper pushHelper;
    @Resource
    private CustomerUserModel customerUserModel;
    @Resource
    private UserModel userModel;
    @Resource
    private CommunicatePlanUserModel communicatePlanUserModel;
    @Resource
    private DingRobotService dingRobotService;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private CustomerCommunicateService customerCommunicateService;

    @Override
    public List<Integer> type() {
        return Collections.singletonList(XbbRefTypeEnum.COMMUNICATE_PLAN.getCode());
    }

    @Override
    public void save(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        Data pojoData = workflowTransferPOJO.getData();
        JSONObject data = pojoData.getData();
        String corpid = workflowTransferPOJO.getCorpid();
        Long dataId = pojoData.getId();
        User user = workflowTransferPOJO.getUser();

        //文件柜数据保存
        saveDataCabinetFile(workflowTransferPOJO);

        Long newCustomerId = FastJsonHelper.getLongOrDefaultFromFormData(data, CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), 0L);
        HashMap<String, Object> param = new HashMap<>();
        param.put(StringConstant.CORPID, corpid);
        param.put("dataId", dataId);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        List<CommunicatePlanUserEntity> communicatePlanUserEntities = communicatePlanUserModel.findEntitys(param);
        Set<String> userList = new HashSet<>();
        if (CollectionUtils.isNotEmpty(communicatePlanUserEntities)){
            communicatePlanUserEntities.forEach(item -> userList.add(item.getUserId()));
        }
//        List<String> userList = saveExecutor2CommunicatePlanUser(data, CommunicatePlanEnum.EXECUTOR.getAttr(), CommunicatePlanEnum.EXECUTOR_LINKED_TEXT.getAttr(), newCustomerId, corpid, dataId, user.getUserId());

        List<String> pushUserList = new ArrayList<>();
        Integer notifyType = getIntegerFromFormData(data, CommunicatePlanEnum.NOTIFY_TYPE.getAttr());
        if (!Objects.equals(workflowTransferPOJO.getIsImport(), 1)) {
            // 访客计划新建消息推送
            CommunicatePlanPushSet communicatePlanPushSet = new CommunicatePlanPushSet();
            PushSetEntity pushSetEntity = communicatePlanPushSet.getPushSet(corpid, PushTypeEnum.COMMUNICATE_PLAN_ADD_PUSH.getSubCode(), pushSetModel);
            if (Objects.equals(pushSetEntity.getEnable(), 1)) {
                String pushObjectString = pushSetEntity.getPushObject();
                JSONObject pushObject = JsonHelperUtil.parseObject(pushObjectString);
                String typeString = pushObject.getString("type");
                JSONArray typeJsonArray = JsonHelperUtil.parseArray(typeString);
                for (Object object : typeJsonArray) {
                    JSONObject jsonObject = (JSONObject) object;
                    Integer enable = jsonObject.getInteger("enable");
                    if (Objects.equals(enable, 1)) {
                        String alias = jsonObject.getString("alias");
                        if (Objects.equals(alias, PushObjectTypeEnum.EXECUTOR.getAlias())) {
                            pushUserList.addAll(userList);
                        }
                    }
                }
                UserEntity userEntity = new UserEntity();
                BeanUtil.copyProperties(user, userEntity);
                pushUserList.addAll(pushHelper.getPushUserIdList(userEntity, pushObjectString, pushUserList, DateUtil.getInt()));
                pushUserList.remove(user.getUserId());
                PushRefTypePojo.Options options = new PushRefTypePojo.Options(pojoData.getAppId(), pojoData.getMenuId(), pojoData.getFormId(), dataId, Collections.singletonList(dataId), SaasMarkEnum.SAAS.getCode(), pojoData.getBusinessType(), pojoData.getSubBusinessType());
                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(dataId), 0, null, I18nMessageUtil.getMessage(CommunicatePlanPushConstant.COMMUNICATE_PLAN_NEW_TITLE), String.format(I18nMessageUtil.getMessage(CommunicatePlanPushConstant.COMMUNICATE_PLAN_NEW_CONTENT), user.getName(), data.getString(CommunicatePlanEnum.NAME.getAttr())), null, options);
                messageService.delayPushDingtalkOAMessage(messageRabbitMqDTO, PushTypeEnum.COMMUNICATE_PLAN_ADD_PUSH);
            }
        }

        //访客计划提醒保存(新建访客计划时同时保存消息)
        if (!Objects.equals(notifyType, CommunicatePlanNotifyTypeEnum.NO_NOTIFY.getCode())) {
            pushUserList.clear();
            pushUserList.addAll(userList);
            Long pushTime = data.getLong(CommunicatePlanEnum.NOTIFY_TIME.getAttr());
            PushRefTypePojo.Options optionsRemind = new PushRefTypePojo.Options(pojoData.getAppId(), pojoData.getMenuId(), pojoData.getFormId(), dataId, Collections.singletonList(dataId), SaasMarkEnum.SAAS.getCode(), pojoData.getBusinessType(), pojoData.getSubBusinessType());
            MessageRabbitMqDTO messageRabbitMqDTORemind = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(dataId), 1, pushTime, data.getString(CommunicatePlanEnum.NAME.getAttr()), data.getString(CommunicatePlanEnum.MEMO.getAttr()), null, optionsRemind);
            messageService.insertPushData(messageRabbitMqDTORemind, PushTypeEnum.COMMUNICATE_PLAN_PUSH);
        }


        try {
            PaasFormDataEntityExt paasFormDataEntityExt = new PaasFormDataEntityExt();
            paasFormDataEntityExt.setData(data);
            paasFormDataEntityExt.setId(dataId);
            paasFormDataEntityExt.setFormId(pojoData.getFormId());
            paasFormDataEntityExt.setMenuId(pojoData.getMenuId());
            paasFormDataEntityExt.setAppId(pojoData.getAppId());
            paasFormDataEntityExt.setCorpid(corpid);
            dingRobotService.sendRobotByBusinessType(corpid, user.getUserId(), user.getName(), paasFormDataEntityExt, XbbRefTypeEnum.COMMUNICATE_PLAN);
        } catch (Exception e) {
            log.error("访客计划发送群消息出错", e);
        }

        try{
            if(isNotDistributeBusinessType(workflowTransferPOJO)) {
                PaasFormEntity paasForm = proFormHelp.getPaasForm(pojoData.getFormId(), pojoData.getBusinessType(), corpid);
                String paasFormName = XbbRefTypeEnum.COMMUNICATE_PLAN.getName();
                if (Objects.nonNull(paasForm)) {
                    paasFormName = paasForm.getName();
                }

                UserEntity userEntity = userModel.getByKey(user.getUserId(), corpid);
                String memo = Objects.equals(workflowTransferPOJO.getIsImport(), BasicConstant.ONE) ? CrmLogMemoConstant.DYNAMIC_USER_IMPORT : CrmLogMemoConstant.DYNAMIC_USER_ADD;
                CustomerDynamicAddDTO customerDynamicAddDTO = new CustomerDynamicAddDTO();
                customerDynamicAddDTO.setCorpid(corpid);
                customerDynamicAddDTO.setUserId(user.getUserId());
                customerDynamicAddDTO.setMemo(String.format(I18nMessageUtil.getMessage(memo), userEntity.getName(), paasFormName));
                customerDynamicAddDTO.setCustomerId(newCustomerId);
                customerDynamicAddDTO.setCustomerName("");
                customerDynamicAddDTO.setDataId(dataId);
                customerDynamicAddDTO.setCommunicateBusinessType(XbbRefTypeEnum.COMMUNICATE_PLAN.getCode());
                customerDynamicAddDTO.setCommunicateBusinessText(data.getString(CommunicatePlanEnum.NAME.getAttr()));
                customerDynamicAddDTO.setLogType(ProjectLogEnum.CUSTOMER_COMMUNICATE_PLAN_CREATE.getSubType());
                customerDynamicAddDTO.setPlatform(PlatFormEnum.INTERNAL.getValue());
                customerCommunicateService.addCustomerDynamic(customerDynamicAddDTO);
            }
        }catch (Exception e){
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowCommunicatePlanStrategy.save", e);
        }
        addLinkDataDynamic(workflowTransferPOJO);
        // api
        apiHook(workflowTransferPOJO);
        // log
        afterSaveLog(workflowTransferPOJO);
    }

    @Override
    public void update(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        User user = workflowTransferPOJO.getUser();
        Data pojoData = workflowTransferPOJO.getData();
        JSONObject data = pojoData.getData();
        Long dataId = pojoData.getId();

        String corpid = workflowTransferPOJO.getCorpid();
        String userId = user.getUserId();
        Long newCustomerId = FastJsonHelper.getLongOrDefaultFromFormData(data, CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), 0L);
//        saveExecutor2CommunicatePlanUser(data, CommunicatePlanEnum.EXECUTOR.getAttr(), CommunicatePlanEnum.EXECUTOR_LINKED_TEXT.getAttr(), newCustomerId, corpid, dataId, userId);

        // log
        afterUpdateLog(workflowTransferPOJO);
    }

    @Override
    public void updateBack(Long taskId, WorkflowTransferPOJO workflowTransferPOJO) {
        // 没有审批无需还原
    }

    @Override
    public void approvalFailed(Long taskId, WorkflowTransferPOJO workflowTransferPOJO, Integer taskType) throws XbbException {
        // 没有审批无需处理
    }

    /**
     * 保存执行人到计划协同团队表
     *
     * @param data               数据
     * @param executor           执行人属性
     * @param executorLinkedText 执行人关联属性
     * @param linkCustomerId     关联客户id
     * @param corpid             公司id
     * @param id                 访客计划id
     * @param userId             员工id
     * @author feng.zheng
     * @date 2019/2/14 22:06
     */
    public List<String> saveExecutor2CommunicatePlanUser(JSONObject data, String executor, String executorLinkedText, Long linkCustomerId, String corpid, Long id, String userId) throws XbbException {
        //执行人员
        List<String> thisUserIds = new ArrayList<>();
        if (data == null || executor == null || executorLinkedText == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
        }
        try {
            boolean isManager = false;
            boolean isCooper = false;
            boolean isCustom = false;
            JSONArray checkArray = data.getJSONArray(executor);
            for (Object obj : checkArray) {
                Integer check = Integer.parseInt(obj.toString());
                if (Objects.equals(check, ExecutorCheckBoxEnum.MAIN_USER_CHECK.getCode())) {
                    isManager = true;
                }
                if (Objects.equals(check, ExecutorCheckBoxEnum.COOPER_USER_CHECK.getCode())) {
                    isCooper = true;
                }
                if (Objects.equals(check, ExecutorCheckBoxEnum.CUSTOM_CHECK.getCode())) {
                    isCustom = true;
                }
            }
            Map<Long, List<String>> customerMainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, List<String>> customerCoopUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (isManager || isCooper) {
                //查找所有客户的协同团队
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("del", 0);
                param.put("customerId", linkCustomerId);
                param.put("corpid", corpid);
                List<CustomerUserEntity> customerUserList = customerUserModel.findEntitys(param);
                for (CustomerUserEntity customerUserEntity : customerUserList) {
                    String cUserId = customerUserEntity.getUserId();
                    Integer isMain = customerUserEntity.getIsMain() == null ? 0 : customerUserEntity.getIsMain();
                    List<String> mainUser = customerMainUserMap.get(linkCustomerId) == null ? new ArrayList<>() : customerMainUserMap.get(linkCustomerId);
                    List<String> coopUser = customerCoopUserMap.get(linkCustomerId) == null ? new ArrayList<>() : customerCoopUserMap.get(linkCustomerId);
                    if (isMain == 1) {
                        mainUser.add(cUserId);
                    } else if (isMain == 0) {
                        coopUser.add(cUserId);
                    }
                    customerMainUserMap.put(linkCustomerId, mainUser);
                    customerCoopUserMap.put(linkCustomerId, coopUser);
                }
            }

            JSONArray userArray = data.getJSONArray(executorLinkedText);
            if (isCustom && userArray != null) {
                for (Object userObj : userArray) {
                    String customUserId = userObj.toString();
                    thisUserIds.add(customUserId);
                }
            }
            // 负责人
            if (isManager) {
                List<String> thisMainUsers = customerMainUserMap.get(linkCustomerId);
                if (thisMainUsers != null) {
                    thisUserIds.addAll(thisMainUsers);
                }
            }
            // 协同人
            if (isCooper) {
                List<String> thisCoopUsers = customerCoopUserMap.get(linkCustomerId);
                if (thisCoopUsers != null) {
                    thisUserIds.addAll(thisCoopUsers);
                }
            }
            // 保存
            if (!thisUserIds.isEmpty()) {
                //添加执行人
                Map<String, Object> userParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                userParam.clear();
                userParam.put("del", 0);
                userParam.put("corpid", corpid);
                userParam.put("userIdIn", thisUserIds);
                List<UserEntity> users = userModel.findEntitys(userParam);
                List<CommunicatePlanUserEntity> CommunicatePlanUserEntityList = new ArrayList<>();
                for (UserEntity user : users) {
                    CommunicatePlanUserEntity planUser = new CommunicatePlanUserEntity();
                    planUser.setCorpid(corpid);
                    planUser.setDataId(id);
                    planUser.setUserId(user.getUserId());
                    planUser.setUserName(user.getName());
                    planUser.setUserAvatar(user.getAvatar());
                    planUser.setIsCreator(userId.equals(user.getUserId()) ? 1 : 0);
                    CommunicatePlanUserEntityList.add(planUser);
                }
                communicatePlanUserModel.insertBatch(CommunicatePlanUserEntityList);
            }
        } catch (Exception e) {
            log.error("保存执行人到计划协同团队表出错:",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
        return thisUserIds;
    }
}
